
/*
 * @项目名称: 模板开发
 * @FilePath: /meek/src/data/json/geojson.js
 * @Author: 1106408264@qq.com
 * @Date: 2017-07-12T16:45:56+08:00
 * @LastEditors: yangxianghong@datatang.com
 * @LastEditTime: 2022-12-23 12:49:03
 * Copyright (c) 2018-2022
 */

/**
 * Created by zhangyong on 2017/7/12.
 */

import Geometry from '../../geometry/geometry'
import Point from '../../geometry/point'
import Polygon from '../../geometry/polygon'
import MutilPolygon from '../../geometry/mutilpolygon'
import Cube from '../../geometry/cube'
import Line from '../../geometry/line'
import Extent from '../../geometry/extent'
import Parallelogram from '../../geometry/parallelogram'
import TiltRectangle from '../../geometry/tiltrectangle'
import Trapezium from '../../geometry/trapezium'
import Feature from '../../meek/feature'
import Obj from '../../utils/obj'
import SquareX from '../../geometry/squarex'
import Circle from './../../geometry/circle';
import Ellipse from './../../geometry/ellipse';

/**
 *
 */
export default class GeoJSON {

  /**
   * 解析 GeoJSON 并返回 Feature 的集合
   *
   * @static
   * @method read
   * @param json geojson格式的数据
   * @returns {Array} 返回 features 的集合
   */
  static read(json) {
    const features = []

    if (!json) {
      return
    }
    const featuresObj = json.features
    featuresObj.forEach(featureObj => {
      if (featureObj.type === 'Feature') {
        if (featureObj.geometry) {
          let constructor = undefined
          const geometryObj = featureObj.geometry
          const geometryType = geometryObj.type
          if (geometryType === 'Point') {
            constructor = Point
          } else if (geometryType === 'LineString') {
            constructor = Line
          } else if (geometryType === 'Polygon') {
            constructor = Polygon
          } else if (geometryType === 'ExtentPolygon') {
            constructor = Extent
          } else if (geometryType === 'MutilPolygon') {
            constructor = MutilPolygon
          } else if (geometryType === 'Cube') {
            constructor = Cube
          } else if (geometryType === 'ParallelogramPolygon') {
            constructor = Parallelogram
          } else if (geometryType === 'TiltRectangle') {
            constructor = TiltRectangle
          } else if (geometryType === 'Trapezium') {
            constructor = Trapezium
          } else if (geometryType === 'SquareX') {
            constructor = SquareX
          } else if (geometryType === Geometry.CIRCLE) {
            constructor = Circle
          } else if (geometryType === Geometry.ELLIPSE) {
            constructor = Ellipse
          }


          if (constructor === undefined) {
            throw new Error('包含未定义的 Geometry 类型')
          } else {
            const coordinates = geometryObj.coordinates
            const geometry = new constructor()
            if (geometryType === "Cube") {
              geometry.readCoordinates(coordinates);
            } else {
              geometry.setCoordinates(coordinates)
            }

            if(constructor === Line) {
              geometry.lineMode = geometryObj.lineMode || 1
            }

            if (geometryType === "Cube") {
              geometry.cubeMode = geometryObj.cubeMode || Cube.cubeMode;
            }

            let propertiesObj
            if (featureObj.properties) {
              propertiesObj = featureObj.properties
            }

            let title = featureObj.title
            const feature = new Feature(geometry, propertiesObj, title)
            features.push(feature)
          }
        }
      }
    })

    return features
  }

  static readSingle(featureObj) {
    let constructor = undefined
    const geometryObj = featureObj.geometry
    const showCentralPoint = featureObj.showCentralPoint

    const geometryType = geometryObj.type
    if (geometryType === 'Point') {
      constructor = Point
    } else if (geometryType === 'LineString') {
      constructor = Line
    } else if (geometryType === 'Polygon' || geometryType === "Square") {
      constructor = Polygon
    } else if (geometryType === 'ExtentPolygon') {
      constructor = Extent
    } else if (geometryType === 'MutilPolygon') {
      constructor = MutilPolygon
    } else if (geometryType === 'Cube') {
      constructor = Cube
    } else if (geometryType === 'Parallelogram') {
      constructor = Parallelogram
    } else if (geometryType === 'TiltRectangle') {
      constructor = TiltRectangle
    } else if (geometryType === 'Trapezium') {
      constructor = Trapezium
    } else if (geometryType === 'SquareX') {
      constructor = SquareX
    } else if (geometryType === Geometry.CIRCLE) {
      constructor = Circle
    } else if (geometryType === Geometry.ELLIPSE) {
      constructor = Ellipse
    }

    if (constructor === undefined) {
      throw new Error('包含未定义的 Geometry 类型')
    } else {
      const coordinates = geometryObj.coordinates
      const geometry = new constructor()
      if (geometryType === "Cube") {
        geometry.readCoordinates(coordinates);
      } else if (geometryType === "LineString" || geometryType === "Polygon") {
        geometry.readCoordinates(coordinates, geometryObj.types);
      } else {
        geometry.setCoordinates(coordinates)
      }

      if (geometryType === "Cube") {
        geometry.cubeMode = geometryObj.cubeMode || Cube.cubeMode;
      }
      if(constructor === Line) {
        geometry.lineMode = geometryObj.lineMode || 1
      }

      if (geometryType === "Square") {
        geometry.fixedPointSize = 4;
      }

      let propertiesObj
      if (featureObj.properties) {
        propertiesObj = featureObj.properties
      }

      let title = featureObj.title
      const feature = new Feature(geometry, propertiesObj, title)
      feature.centralPoint = showCentralPoint;
      return feature;
    }
  }

  /**
   *
   * 将 Feature 集合写入到 GeoJSON 的格式对象中
   *
   * @static
   * @method write
   * @param features Feature 集合
   * @returns {Object} 返回 GeoJSON 格式的数据
   */
  static write(features) {
    const featuresArr = []

    features.forEach(feature => {
      const type = GeoJSON.getGeoJSONGeometryType(feature.geometry, feature)
      const properties = Obj.mapToObject(feature._attributesMap);
      delete properties["shapeType"];
      const sharedEdges = properties["sharedEdges"];
      if (sharedEdges) {
        properties["sharedEdges"] = sharedEdges.map(item => {
          let id;
          if (item.get("id1") === properties["id"]) {
            id = item.get("id2")
          } else {
            id = item.get("id1")
          }
          return {
            id,
            coords: item.geometry.getCoordinates()
          }
        })
      }
      let obj = {
        type: 'Feature',
        geometry: {
          type,
          coordinates: feature.geometry.getCoordinates()
        },
        properties: properties,

        title: feature.displayText
      }
      console.log("obj", obj)
      if (type === "Cube") {
        obj.geometry.coordinates = feature.geometry.exportCoordinates();
        //const vertexes = Cube.getCubeEightVertexs(feature.geometry.getCoordinates(), feature.geometry.isLeft);
        //obj.geometry.vertexes = vertexes;
        //obj.geometry.visibleAreas = feature.geometry.getAreaOfVisibleFaces();
        obj.geometry.cubeMode = feature.geometry.cubeMode;
      }
      featuresArr.push(obj)
    })

    return {
      type: 'FeatureCollection',
      features: featuresArr
    }
  }

  /**
   * 获取Geometry的类型
   *
   * @static
   * @method getGeoJSONGeometryType
   * @param geometry
   * @returns {*}
   */
  static getGeoJSONGeometryType(geometry, feature) {
    const type = geometry.geometryType
    let jsonType
    switch (type) {
      case Geometry.POINT:
        jsonType = 'Point'
        break
      case Geometry.LINE:
        jsonType = 'LineString'
        break
      case Geometry.POLYGON:
        if (feature && feature.get("shapeType") === "Square") {
          jsonType = 'Square';
        } else if (geometry.fixedPointSize === 4) {
          jsonType = "Square";
        } else {
          jsonType = 'Polygon'
        }
        break
      case Geometry.MULTI_POLYGON:
        jsonType = 'MutilPolygon'
        break
      case Geometry.CUBE:
        jsonType = 'Cube'
        break
      case Geometry.EXTENT:
        jsonType = 'ExtentPolygon'
        break
      case Geometry.PARALLELOGRAM:
        jsonType = 'Parallelogram'
        break
      case Geometry.TILTRECTANGLE:
        jsonType = 'TiltRectangle'
        break
      case Geometry.TRAPEZIUM:
        jsonType = 'Trapezium'
        break
      case Geometry.SQUAREX:
        jsonType = 'SquareX'
        break
      case Geometry.CIRCLE:
        jsonType = Geometry.CIRCLE
        break
      case Geometry.ELLIPSE:
        jsonType = Geometry.ELLIPSE
        break
    }
    return jsonType
  }
}
